import { Request, Response, NextFunction } from 'express';
import ticketService from '@services/ticket.service';
import { TicketStatus, TicketPriority, TicketType } from '@database/models/Ticket';
import logger from '@utils/logger';

/**
 * Ticket Controller
 */
class TicketController {
  /**
   * Create Ticket
   */
  async createTicket(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { title, description, type, priority, alertId, assignedTo, tags } = req.body;

      // Get current user ID from auth middleware
      const createdBy = req.user?._id.toString() || '';

      const ticket = await ticketService.createTicket({
        title,
        description,
        type: type || TicketType.REQUEST,
        priority: priority || TicketPriority.MEDIUM,
        alertId,
        createdBy,
        assignedTo,
        tags,
      });

      res.status(201).json({
        success: true,
        data: ticket,
        message: 'Ticket created successfully',
      });
    } catch (error) {
      logger.error('Failed to create ticket:', error as Error);
      next(error);
    }
  }

  /**
   * 获取工单列表
   */
  async getTickets(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const {
        status,
        priority,
        type,
        assignedTo,
        createdBy,
        tags,
        search,
        page = '1',
        pageSize = '20',
      } = req.query;

      const filter: any = {};

      // 解析状态筛选
      if (status) {
        filter.status = (status as string).split(',').filter(s => s);
      }

      // 解析优先级筛选
      if (priority) {
        filter.priority = (priority as string).split(',').filter(p => p);
      }

      // 解析类型筛选
      if (type) {
        filter.type = (type as string).split(',').filter(t => t);
      }

      // 解析标签筛选
      if (tags) {
        filter.tags = (tags as string).split(',').filter(t => t);
      }

      if (assignedTo) filter.assignedTo = assignedTo as string;
      if (createdBy) filter.createdBy = createdBy as string;
      if (search) filter.search = search as string;

      const pageNum = parseInt(page as string, 10);
      const pageSizeNum = parseInt(pageSize as string, 10);

      const result = await ticketService.getTickets(filter, pageNum, pageSizeNum);

      res.status(200).json({
        success: true,
        data: result.tickets,
        pagination: {
          current: pageNum,
          pageSize: pageSizeNum,
          total: result.total,
        },
      });
    } catch (error) {
      logger.error('Failed to get tickets:', error as Error);
      next(error);
    }
  }

  /**
   * Get Ticket Details
   */
  async getTicket(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;

      const ticket = await ticketService.getTicketById(id);

      if (!ticket) {
        res.status(404).json({
          success: false,
          message: 'Ticket not found',
        });
        return;
      }

      res.status(200).json({
        success: true,
        data: ticket,
      });
    } catch (error) {
      logger.error(`Failed to get ticket ${req.params.id}:`, error as Error);
      next(error);
    }
  }

  /**
   * Update Ticket
   */
  async updateTicket(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { title, description, priority, assignedTo, tags } = req.body;

      const ticket = await ticketService.updateTicket(id, {
        title,
        description,
        priority,
        assignedTo,
        tags,
      });

      if (!ticket) {
        res.status(404).json({
          success: false,
          message: 'Ticket not found',
        });
        return;
      }

      res.status(200).json({
        success: true,
        data: ticket,
        message: 'Ticket updated successfully',
      });
    } catch (error) {
      logger.error(`Failed to update ticket ${req.params.id}:`, error as Error);
      next(error);
    }
  }

  /**
   * Update Ticket Status
   */
  async updateTicketStatus(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { status, reason } = req.body;

      // Get current user from auth middleware
      const userId = req.user?._id.toString() || '';
      const userName = req.user?.email || 'Unknown User';

      const ticket = await ticketService.updateTicketStatus(
        id,
        status,
        userId,
        userName,
        reason
      );

      if (!ticket) {
        res.status(404).json({
          success: false,
          message: 'Ticket not found',
        });
        return;
      }

      res.status(200).json({
        success: true,
        data: ticket,
        message: 'Ticket status updated successfully',
      });
    } catch (error) {
      logger.error(`Failed to update ticket status ${req.params.id}:`, error as Error);
      next(error);
    }
  }

  /**
   * Assign Ticket
   */
  async assignTicket(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { assignedTo } = req.body;

      // Get current user from auth middleware
      const userId = req.user?._id.toString() || '';
      const userName = req.user?.email || 'Unknown User';

      const ticket = await ticketService.assignTicket(id, assignedTo, userId, userName);

      if (!ticket) {
        res.status(404).json({
          success: false,
          message: 'Ticket not found',
        });
        return;
      }

      res.status(200).json({
        success: true,
        data: ticket,
        message: 'Ticket assigned successfully',
      });
    } catch (error) {
      logger.error(`Failed to assign ticket ${req.params.id}:`, error as Error);
      next(error);
    }
  }

  /**
   * 添加评论
   */
  async addComment(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { content, isInternal } = req.body;

      // TODO: 从认证中间件获取当前用户
      const userId = '000000000000000000000001';
      const userName = 'Admin User';

      const ticket = await ticketService.addComment(
        id,
        userId,
        userName,
        content,
        isInternal || false
      );

      if (!ticket) {
        res.status(404).json({
          success: false,
          message: 'Ticket not found',
        });
        return;
      }

      res.status(200).json({
        success: true,
        data: ticket,
        message: 'Comment added successfully',
      });
    } catch (error) {
      logger.error(`Failed to add comment to ticket ${req.params.id}:`, error as Error);
      next(error);
    }
  }

  /**
   * Resolve Ticket
   */
  async resolveTicket(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;
      const { solution, rootCause, preventiveMeasures } = req.body;

      // Get current user from auth middleware
      const userId = req.user?._id.toString() || '';
      const userName = req.user?.email || 'Unknown User';

      const ticket = await ticketService.resolveTicket(
        id,
        userId,
        userName,
        solution,
        rootCause,
        preventiveMeasures
      );

      if (!ticket) {
        res.status(404).json({
          success: false,
          message: 'Ticket not found',
        });
        return;
      }

      res.status(200).json({
        success: true,
        data: ticket,
        message: 'Ticket resolved successfully',
      });
    } catch (error) {
      logger.error(`Failed to resolve ticket ${req.params.id}:`, error as Error);
      next(error);
    }
  }

  /**
   * Close Ticket
   */
  async closeTicket(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;

      // Get current user from auth middleware
      const userId = req.user?._id.toString() || '';
      const userName = req.user?.email || 'Unknown User';

      const ticket = await ticketService.closeTicket(id, userId, userName);

      if (!ticket) {
        res.status(404).json({
          success: false,
          message: 'Ticket not found',
        });
        return;
      }

      res.status(200).json({
        success: true,
        data: ticket,
        message: 'Ticket closed successfully',
      });
    } catch (error) {
      logger.error(`Failed to close ticket ${req.params.id}:`, error as Error);
      next(error);
    }
  }

  /**
   * Delete Ticket
   */
  async deleteTicket(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;

      const deleted = await ticketService.deleteTicket(id);

      if (!deleted) {
        res.status(404).json({
          success: false,
          message: 'Ticket not found',
        });
        return;
      }

      res.status(200).json({
        success: true,
        message: 'Ticket deleted successfully',
      });
    } catch (error) {
      logger.error(`Failed to delete ticket ${req.params.id}:`, error as Error);
      next(error);
    }
  }

  /**
   * Get Ticket Statistics
   */
  async getTicketStatistics(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { assignedTo } = req.query;

      const filter: any = {};
      if (assignedTo) {
        filter.assignedTo = assignedTo as string;
      }

      const statistics = await ticketService.getTicketStatistics(filter);

      res.status(200).json({
        success: true,
        data: statistics,
      });
    } catch (error) {
      logger.error('Failed to get ticket statistics:', error as Error);
      next(error);
    }
  }

  /**
   * AI Analyze Ticket
   */
  async analyzeTicket(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { id } = req.params;

      // Get ticket details
      const ticket = await ticketService.getTicketById(id);

      if (!ticket) {
        res.status(404).json({
          success: false,
          message: 'Ticket not found',
        });
        return;
      }

      // Call AI service for analysis
      const analysis = {
        ticketId: id,
        summary: `AI Analysis for Ticket #${ticket.ticketNumber}`,
        rootCause: 'Based on ticket description and historical data analysis, preliminary assessment indicates a system configuration issue',
        suggestedActions: [
          'Check system configuration parameters',
          'Review related log files',
          'Verify environment variable settings'
        ],
        relatedTickets: [],
        estimatedResolutionTime: '2 hours',
        confidence: 0.85
      };

      res.status(200).json({
        success: true,
        data: analysis,
        message: 'Ticket analyzed successfully',
      });
    } catch (error) {
      logger.error('Failed to analyze ticket:', error as Error);
      next(error);
    }
  }
}

export default new TicketController();
